package com.yinhe.music.yhmusic.websocket;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.text.TextUtils;

import com.yinhe.music.yhmusic.BuildConfig;
import com.yinhe.music.yhmusic.application.MusicApplication;
import com.yinhe.music.yhmusic.log.MLog;

import java.net.URISyntaxException;

import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

/**
 * Created by Johnson on 2018/3/6.
 */

public class WsManager {

    private final static String TAG = "WsManger";


    private static WsManager mInstance;

    private static final int FRAME_QUEUE_SIZE = 5;
    private static final int CONNECT_TIMEOUT = 5000;
    private static final String DEF_TEST_URL = "http://123.57.205.224:6868/";//测试服默认地址
    private static final String DEF_RELEASE_URL = "http://123.57.205.224:6868/";//正式服默认地址
    private static final String DEF_URL = BuildConfig.DEBUG ? DEF_TEST_URL : DEF_RELEASE_URL;
    private String url;

    private Socket mSocket;


    private WsManager() {
    }

    public static WsManager getInstance(){
        if(mInstance == null){
            synchronized (WsManager.class){
                if(mInstance == null){
                    mInstance = new WsManager();
                }
            }
        }
        return mInstance;
    }

    public void init(){
        try {
            /**
             * configUrl其实是缓存在本地的连接地址
             * 这个缓存本地连接地址是app启动的时候通过http请求去服务端获取的,
             * 每次app启动的时候会拿当前时间与缓存时间比较,超过6小时就再次去服务端获取新的连接地址更新本地缓存
             */
            String configUrl = "";
            url = TextUtils.isEmpty(configUrl) ? DEF_URL : configUrl;
            mSocket = IO.socket(url);
            addEvents();
            mSocket.connect();

            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mSocket.emit("shanxuan666", "fuck");
                }
            }, 5000);


            MLog.info(TAG, "第一次连接");
        } catch (URISyntaxException e) {
            MLog.info(TAG, "第一次连接 e " + e);
            e.printStackTrace();
        }
    }


    private void addEvents() {
        mSocket.on("connect", mConnectListener);
        mSocket.on("server_response", mServerResponseListener);
    }

    private void clearEvents() {
        mSocket.off("connect", mConnectListener);
        mSocket.off("server_response", mServerResponseListener);

    }

    private Emitter.Listener mConnectListener = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            if (args != null && args.length > 0)
            MLog.info(TAG,"args[0] = " + args[0]);
        }
    };

    private Emitter.Listener mServerResponseListener = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            if (args != null && args.length > 0)
                MLog.info(TAG,"args[0] = " + args[0]);
        }
    };


    public void disconnect(){
        if(mSocket != null) {
            clearEvents();
            mSocket.disconnect();
            mSocket = null;
        }
    }

    private Handler mHandler = new Handler();

    private int reconnectCount = 0;//重连次数
    private long minInterval = 3000;//重连最小时间间隔
    private long maxInterval = 60000;//重连最大时间间隔


    public void reconnect() {
        if (!isNetConnect()) {
            reconnectCount = 0;
            MLog.info(TAG,"重连失败网络不可用");
            return;
        }

        //这里其实应该还有个用户是否登录了的判断 因为当连接成功后我们需要发送用户信息到服务端进行校验
        //由于我们这里是个demo所以省略了
        if (mSocket != null &&
                !mSocket.connected()) {//不是正在重连状态

            reconnectCount++;

            long reconnectTime = minInterval;
            if (reconnectCount > 3) {
                url = DEF_URL;
                long temp = minInterval * (reconnectCount - 2);
                reconnectTime = temp > maxInterval ? maxInterval : temp;
            }

            MLog.info(TAG,"准备开始第%d次重连,重连间隔%d -- url:%s", reconnectCount, reconnectTime, url);
//            cancelReconnect();
            mHandler.postDelayed(mReconnectTask, reconnectTime);
        }
    }


    private Runnable mReconnectTask = new Runnable() {

        @Override
        public void run() {
            try {
                mSocket = IO.socket(url);
                addEvents();
                mSocket.connect();
            } catch (URISyntaxException e) {
                e.printStackTrace();
                reconnect();
            }
        }
    };


    private void cancelReconnect() {
        reconnectCount = 0;
        mHandler.removeCallbacks(mReconnectTask);
    }


    private boolean isNetConnect() {
        ConnectivityManager connectivity = (ConnectivityManager) MusicApplication.getContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo info = connectivity.getActiveNetworkInfo();
            if (info != null && info.isConnected()) {
                // 当前网络是连接的
                if (info.getState() == NetworkInfo.State.CONNECTED) {
                    // 当前所连接的网络可用
                    return true;
                }
            }
        }
        return false;
    }
}
